﻿// Copyright (C) 2012 Jeff Tanner <jeff00seattle@gmail.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Caching;
using System.IO;
using System.Drawing;
using System.Security.Cryptography;
using System.Diagnostics;
using System.ComponentModel;
using System.Data;
using System.Web.SessionState;
using System.Web.UI.HtmlControls;
using System.Web.Script.Serialization;

using WebSlideProjector.Configuration;
using WebSlideProjector.Extensions;
using WebSlideProjector.EventLogs;
using WebSlideProjector.GetFiles;

namespace WebSlideProjector
{
    public partial class _Default : System.Web.UI.Page
    {
        protected class SlideShowImage
        {
            public string image { get; set; }
            public string title { get; set; }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Gets the full pathname of the slide show file. </summary>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected string SlideShowPath
        {
            get
            {
                return this.Context.Server.MapPath(AppSettings.SlideShowFolder);
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by Page for load events. </summary>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void Page_Load(object sender, EventArgs e)
        {
            this.hiddenSlidesJSON.Value = this.getSlidesJSONString();

            this.timerSlidesRefresh.Interval 
                = Convert.ToInt32(Session["SlideShowRefreshMinutes"]) * 1000 * 60;

            this.hiddenSlidesTransistionMode.Value = this.getRandomSlideTransition();

            if (!Page.IsPostBack)
            {
                this.Title = String.Format("{0} - {1}", AppSettings.AssemblyName, AppSettings.AssemblyVersion);
            }
        }

        #region Web Form Designer generated code

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Init" /> event to initialize the page.
        /// </summary>
        ///
        /// <remarks>   Jeff, 2/20/2012. </remarks>
        ///
        /// <param name="e">    An <see cref="T:System.EventArgs" /> that contains the event data. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }

        private void InitializeComponent()
        {
            this.Error += new System.EventHandler(this.SlideShow_Error);
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by SlideShow for error events. </summary>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void SlideShow_Error(object sender, EventArgs e)
        {
            Response.Redirect("~/ErrorPages/Error.aspx", true);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Gets the slides json string. </summary>
        ///
        /// <exception cref="Exception">    Thrown when exception. </exception>
        ///
        /// <returns>   The slides json string. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        private string getSlidesJSONString()
        {
            string strSlidesJSON = String.Empty;
            try
            {
                HashSet<string> hsExtensions = AppSettings.SlideShowFileExtensionSet;
                HashSet<string> hsExemptFolders = AppSettings.SlideShowExemptFolders;
                string[] filePaths = FileHelper.GetFilesRecursive(this.SlideShowPath, hsExemptFolders).Where(f => hsExtensions.Contains(Path.GetExtension(f))).ToArray();

                List<SlideShowImage> images = new List<SlideShowImage>();
                int lengthRootDirectoryPath = this.SlideShowPath.Length;
                char[] trimChars = { '\\' };
                foreach (string filePath in filePaths)
                {
                    string fileName = filePath.Substring(lengthRootDirectoryPath);
                    fileName = fileName.TrimStart(trimChars);
                    fileName = fileName.Replace("\\", "/");
                    string imagePath = AppSettings.SlideShowFolder + "/" + fileName;

                    // Gets the base url in the following format: "http(s)://domain(:port)/AppPath)" 
                    string urlPath = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.ApplicationPath;
                    char[] charsToTrim = {'/', ' '};
                    urlPath = urlPath.TrimEnd(charsToTrim);
                    urlPath += "/" + imagePath;

                    if (Uri.IsWellFormedUriString(urlPath, System.UriKind.Absolute))
                    {
                        images.Add(new SlideShowImage { image = urlPath, title = fileName });
                    }
                }

                strSlidesJSON = images.ToJSON();
            }
            catch (Exception ex)
            {
                HttpContext ctx = HttpContext.Current;
                string origin = ctx.Request.Url.ToString();
                origin += ": _Default.getSlidesJSONString()";

                string exMessageHTML = ex.ToErrorMessageHTML();
                ctx.Response.Write(exMessageHTML);

                WebEventLog log = new WebEventLog();
                log.LogException(ex, origin);
            }

            return strSlidesJSON;
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Gets the random slide transition. </summary>
        ///
        /// <returns>   The random slide transition. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        private string getRandomSlideTransition()
        {
            //0-None, 1-Fade, 2-Slide Top, 3-Slide Right, 4-Slide Bottom, 5-Slide Left, 6-Carousel Right, 7-Carousel Left
            int randomNumber = 0;
            int rangeLow = 1; int rangeHigh = 7;
            if (Int32.TryParse(this.hiddenSlidesTransistionMode.Value, out randomNumber))
            {
                switch (randomNumber)
                {
                    case 0:
                        break;
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                        rangeLow = randomNumber + 1;
                        break;
                    case 5:
                    case 6:
                    case 7:
                        rangeHigh = randomNumber - 1;
                        break;
                }
            }
            Random random = new Random();
            randomNumber = random.Next(rangeLow, rangeHigh);

            return randomNumber.ToString();
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by SlidesRefresh for tick events. </summary>
        ///
        /// <exception cref="ApplicationException"> Thrown when application. </exception>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void SlidesRefresh_Tick(object sender, EventArgs e)
        {
            try
            {
                this.hiddenSlidesJSON.Value = this.getSlidesJSONString();
            }
            catch (Exception ex)
            {
                HttpContext ctx = HttpContext.Current;
                string origin = ctx.Request.Url.ToString();
                origin += ": _Default.SlidesRefresh_Tick()";

                string exMessageHTML = ex.ToErrorMessageHTML();
                ctx.Response.Write(exMessageHTML);

                WebEventLog log = new WebEventLog();
                log.LogException(ex, origin);
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by ProjectorSetupButton for click events. </summary>
        ///
        /// <remarks>   Jeff, 2/20/2012. </remarks>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void ProjectorSetupButton_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
                Response.Redirect("~/ProjectorSetup.aspx");
            }
            catch (System.Threading.ThreadAbortException)
            {
                // Ignore
            }
            catch (Exception ex)
            {
                HttpContext ctx = HttpContext.Current;
                string origin = ctx.Request.Url.ToString();
                string exMessageHTML = ex.ToErrorMessageHTML(origin, System.Reflection.MethodBase.GetCurrentMethod().Name);

                Session["SiteError"] = exMessageHTML;
                Response.Redirect("~/ErrorPages/Error.aspx", true);
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Event handler. Called by SlideCarouselButton for click events. </summary>
        ///
        /// <remarks>   Jeff, 2/20/2012. </remarks>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Event information. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected void SlideCarouselButton_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
                Session["User"] = null;
                if (AppSettings.SlideCarouselLoginMode)
                {
                    Response.Redirect("~/Login.aspx?ReturnUrl=SlideCarousel.aspx");
                }
                else
                {
                    Response.Redirect("~/SlideCarousel.aspx");
                }
            }
            catch (System.Threading.ThreadAbortException)
            {
                // Ignore
            }
            catch (Exception ex)
            {
                HttpContext ctx = HttpContext.Current;
                string origin = ctx.Request.Url.ToString();
                string exMessageHTML = ex.ToErrorMessageHTML(origin, System.Reflection.MethodBase.GetCurrentMethod().Name);

                Session["SiteError"] = exMessageHTML;
                Response.Redirect("~/ErrorPages/Error.aspx", true);
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Raises the error event. </summary>
        ///
        /// <param name="e">    Event information to send to registered event handlers. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        protected override void OnError(EventArgs e)
        {
            Response.Redirect("~/ErrorPages/Error.aspx", true);

            base.OnError(e);
        }
    }
}